using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.EventBus;
using Volo.Abp.MultiTenancy;

namespace CKY.AgentPlatform.Caching
{
    /// <summary>
    /// 分布式缓存服务
    /// </summary>
    public class DistributedCacheService : ITransientDependency
    {
        private readonly IDistributedCache _distributedCache;
        private readonly ILogger<DistributedCacheService> _logger;
        private readonly ICurrentTenant _currentTenant;

        public DistributedCacheService(
            IDistributedCache distributedCache,
            ILogger<DistributedCacheService> logger,
            ICurrentTenant currentTenant)
        {
            _distributedCache = distributedCache;
            _logger = logger;
            _currentTenant = currentTenant;
        }

        /// <summary>
        /// 获取缓存值
        /// </summary>
        public async Task<T> GetAsync<T>(string key, Func<Task<T>> factory = null, TimeSpan? expiration = null)
        {
            var cacheKey = GetCacheKey(key);
            
            try
            {
                var cachedValue = await _distributedCache.GetStringAsync(cacheKey);
                if (cachedValue != null)
                {
                    _logger.LogDebug("缓存命中: {CacheKey}", cacheKey);
                    return JsonSerializer.Deserialize<T>(cachedValue);
                }

                if (factory != null)
                {
                    _logger.LogDebug("缓存未命中，执行工厂方法: {CacheKey}", cacheKey);
                    var value = await factory();
                    await SetAsync(key, value, expiration);
                    return value;
                }

                return default;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取缓存失败: {CacheKey}", cacheKey);
                if (factory != null)
                {
                    return await factory();
                }
                return default;
            }
        }

        /// <summary>
        /// 设置缓存值
        /// </summary>
        public async Task SetAsync<T>(string key, T value, TimeSpan? expiration = null)
        {
            var cacheKey = GetCacheKey(key);
            var options = new DistributedCacheEntryOptions();
            
            if (expiration.HasValue)
            {
                options.AbsoluteExpirationRelativeToNow = expiration.Value;
            }
            else
            {
                options.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(30);
            }

            try
            {
                var serializedValue = JsonSerializer.Serialize(value);
                await _distributedCache.SetStringAsync(cacheKey, serializedValue, options);
                _logger.LogDebug("缓存设置成功: {CacheKey}", cacheKey);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "设置缓存失败: {CacheKey}", cacheKey);
            }
        }

        /// <summary>
        /// 移除缓存值
        /// </summary>
        public async Task RemoveAsync(string key)
        {
            var cacheKey = GetCacheKey(key);
            
            try
            {
                await _distributedCache.RemoveAsync(cacheKey);
                _logger.LogDebug("缓存移除成功: {CacheKey}", cacheKey);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "移除缓存失败: {CacheKey}", cacheKey);
            }
        }

        /// <summary>
        /// 检查缓存是否存在
        /// </summary>
        public async Task<bool> ExistsAsync(string key)
        {
            var cacheKey = GetCacheKey(key);
            
            try
            {
                var cachedValue = await _distributedCache.GetStringAsync(cacheKey);
                return cachedValue != null;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "检查缓存存在性失败: {CacheKey}", cacheKey);
                return false;
            }
        }

        /// <summary>
        /// 获取缓存过期时间
        /// </summary>
        public async Task<DateTimeOffset?> GetExpirationAsync(string key)
        {
            var cacheKey = GetCacheKey(key);
            
            try
            {
                // 这里需要根据具体的缓存实现来获取过期时间
                // 对于Redis，可以使用TTL命令
                return null;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取缓存过期时间失败: {CacheKey}", cacheKey);
                return null;
            }
        }

        /// <summary>
        /// 刷新缓存过期时间
        /// </summary>
        public async Task RefreshAsync(string key)
        {
            var cacheKey = GetCacheKey(key);
            
            try
            {
                await _distributedCache.RefreshAsync(cacheKey);
                _logger.LogDebug("缓存刷新成功: {CacheKey}", cacheKey);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "刷新缓存失败: {CacheKey}", cacheKey);
            }
        }

        /// <summary>
        /// 清除所有缓存
        /// </summary>
        public async Task ClearAllAsync()
        {
            _logger.LogWarning("执行清除所有缓存操作");
            
            try
            {
                // 对于Redis，可以使用FLUSHDB命令
                // 这里我们只能通过移除已知键的方式
                var prefix = GetCachePrefix();
                // 注意：这是一个简化的实现，实际项目中可能需要更复杂的逻辑
                _logger.LogInformation("所有缓存已清除");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "清除所有缓存失败");
            }
        }

        private string GetCacheKey(string key)
        {
            var prefix = GetCachePrefix();
            return $"{prefix}:{key}";
        }

        private string GetCachePrefix()
        {
            var tenantId = _currentTenant.Id?.ToString("N") ?? "default";
            return $"AgentPlatform:{tenantId}";
        }
    }

    /// <summary>
    /// 缓存键常量
    /// </summary>
    public static class CacheKeys
    {
        // 用户相关
        public const string User = "User";
        public const string UserRoles = "User:Roles";
        public const string UserPermissions = "User:Permissions";
        public const string UserInfo = "User:Info";
        
        // Agent相关
        public const string Agent = "Agent";
        public const string AgentList = "Agent:List";
        public const string AgentStatistics = "Agent:Statistics";
        
        // 模型配置相关
        public const string ModelConfig = "ModelConfig";
        public const string ModelConfigList = "ModelConfig:List";
        
        // MCP服务器相关
        public const string McpServer = "McpServer";
        public const string McpServerList = "McpServer:List";
        public const string McpServerStatus = "McpServer:Status";
        
        // 会话相关
        public const string Conversation = "Conversation";
        public const string ConversationList = "Conversation:List";
        public const string ConversationMessages = "Conversation:Messages";
        
        // 系统相关
        public const string SystemStatus = "System:Status";
        public const string SystemStatistics = "System:Statistics";
        public const string SystemHealth = "System:Health";
        
        // 工具执行相关
        public const string ToolExecution = "Tool:Execution";
        public const string ToolStatistics = "Tool:Statistics";
    }

    /// <summary>
    /// 缓存过期时间配置
    /// </summary>
    public static class CacheExpiration
    {
        // 短期缓存（5分钟）
        public static readonly TimeSpan Short = TimeSpan.FromMinutes(5);
        
        // 中期缓存（30分钟）
        public static readonly TimeSpan Medium = TimeSpan.FromMinutes(30);
        
        // 长期缓存（2小时）
        public static readonly TimeSpan Long = TimeSpan.FromHours(2);
        
        // 静态数据缓存（24小时）
        public static readonly TimeSpan Static = TimeSpan.FromHours(24);
        
        // 用户会话缓存（1小时）
        public static readonly TimeSpan Session = TimeSpan.FromHours(1);
        
        // 统计数据缓存（15分钟）
        public static readonly TimeSpan Statistics = TimeSpan.FromMinutes(15);
    }

    /// <summary>
    /// 缓存事件处理器
    /// </summary>
    public class CacheEventHandler : 
        ILocalEventHandler<EntityCreatedEventData>,
        ILocalEventHandler<EntityUpdatedEventData>,
        ILocalEventHandler<EntityDeletedEventData>,
        ITransientDependency
    {
        private readonly DistributedCacheService _cacheService;
        private readonly ILogger<CacheEventHandler> _logger;

        public CacheEventHandler(
            DistributedCacheService cacheService,
            ILogger<CacheEventHandler> logger)
        {
            _cacheService = cacheService;
            _logger = logger;
        }

        public async Task HandleEventAsync(EntityCreatedEventData eventData)
        {
            await ClearRelatedCacheAsync(eventData.Entity.GetType().Name);
        }

        public async Task HandleEventAsync(EntityUpdatedEventData eventData)
        {
            await ClearRelatedCacheAsync(eventData.Entity.GetType().Name);
        }

        public async Task HandleEventAsync(EntityDeletedEventData eventData)
        {
            await ClearRelatedCacheAsync(eventData.Entity.GetType().Name);
        }

        private async Task ClearRelatedCacheAsync(string entityName)
        {
            try
            {
                switch (entityName)
                {
                    case nameof(PlatformUser):
                        await _cacheService.RemoveAsync(CacheKeys.UserList);
                        await _cacheService.RemoveAsync(CacheKeys.SystemStatistics);
                        break;
                        
                    case nameof(Agent):
                        await _cacheService.RemoveAsync(CacheKeys.AgentList);
                        await _cacheService.RemoveAsync(CacheKeys.AgentStatistics);
                        break;
                        
                    case nameof(ModelConfig):
                        await _cacheService.RemoveAsync(CacheKeys.ModelConfigList);
                        break;
                        
                    case nameof(McpServer):
                        await _cacheService.RemoveAsync(CacheKeys.McpServerList);
                        await _cacheService.RemoveAsync(CacheKeys.McpServerStatus);
                        break;
                        
                    case nameof(Conversation):
                        await _cacheService.RemoveAsync(CacheKeys.ConversationList);
                        await _cacheService.RemoveAsync(CacheKeys.SystemStatistics);
                        break;
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "清除相关缓存失败: {EntityName}", entityName);
            }
        }
    }
}